package com.sdy.mvc.exception;

import com.sdy.common.model.BizException;
import com.sdy.common.model.Response;
import com.sdy.mvc.annotation.RemoteService;
import com.sdy.mvc.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by zzq on 2018/6/22.
 */
@Slf4j
@Component
public class WebExceptionResolver implements HandlerExceptionResolver {

    /**
     * 没有区分是哪种情况的异常
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object o, Exception ex) {
        String errorInfo;
        if (ex instanceof BizException) {
            errorInfo = ex.getMessage();
            log.info("业务异常：{}", ex.getMessage());
        } else {
            errorInfo = "服务器异常，请联系管理员。";
            log.error("未知异常：", ex);
        }
        HandlerMethod method = (HandlerMethod) o;
        // ResponseBody.class注解说明是ajax调用，否则返回视图
        if (method != null && (method.getMethod().isAnnotationPresent(ResponseBody.class)
                || method.getBeanType().isAnnotationPresent(RestController.class)
                || method.getBeanType().isAnnotationPresent(RemoteService.class))) {
            try {
                String respJson = JsonUtil.toJson(Response.error(errorInfo));
                resp.setStatus(200);
                resp.setCharacterEncoding("UTF-8");
                resp.setContentType("application/json;charset=UTF-8");
                resp.getWriter().write(respJson == null ? "" : respJson);
                resp.getWriter().flush();
                resp.getWriter().close(); //这里很重要，否则ajax的readystatus为0
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }
        // 统一返回错误视图，否则会继续往外抛出异常
        Map<String, String> map = new HashMap<>();
        map.put("errorInfo", errorInfo);
        return new ModelAndView("/page/error", map);
    }
}
